﻿using System.Collections.Generic;
using Castle.ActiveRecord;
using Longtop.Web.WebSite.Models;
using System.ComponentModel;
using System.Web.Routing;
using NHibernate.Criterion;
using Longtop.Web.SaleWeb.Models;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Linq;
using System;
using System.Text;
using Discuz.Entity;
namespace Longtop.Web.WebSite.Models {
    public partial class Lable {

        static int _departmentLableId;
        static int _departmentDefaultId;
        public static int DepartmentLableId {
            get {
                if (_departmentLableId > 0) return _departmentLableId;
                _departmentLableId = Lable.FindFirst(Expression.Eq("Text", "部门管理")).LableId;
                return _departmentLableId;
            }
        }
        public static int DepartmentDefaultId {
            get {
                if (_departmentDefaultId > 0) return _departmentDefaultId;
                _departmentDefaultId = Lable.FindFirst(Expression.Eq("ClassId", DepartmentLableId)).LableId;
                return _departmentDefaultId;
            }
        }
        [HasMany(typeof(RolePermission), ColumnKey = "lable_id", Table = "RolePermission", Lazy = true)]
        public virtual IList<RolePermission> RolePermissions {
            get;
            set;
        }

        [HasAndBelongsToMany(typeof(Sale),
Table = "UserInDepartment", ColumnKey = "department_id", ColumnRef = "user_name", Lazy = true)]
        public virtual IList<Sale> Sales {
            get;
            set;
        }

        [HasMany(typeof(Achievement), ColumnKey = "department_id", Table = "Achievement", Lazy = true)]
        public virtual IList<Achievement> Achievements {
            get;
            set;
        }


        public static IList<Lable> GetAllDepartments() {
            return Lable.FindAll(Expression.Eq("ClassId", DepartmentLableId));
        }
    }
}
namespace Longtop.Web.SaleWeb.Models {

    public static class Extentsion {
        public static decimal GetMonthTask(this Lable department) {
            return department.Sales.Sum(p => p.GetTask(null));
        }
        public static decimal GetMonthTask(this Lable department, DateTime datetime) {
            return department.Sales.Sum(p => p.GetTask(datetime));
        }
        public static decimal GetTodayAchieve(this Lable department) {
            return department.Achievements.Where(x => DateTime.Today.Date.Equals(x.CreateDT.Date)).Sum(a => a.Reached);
        }

        public static decimal GetMonthAchieve(this Lable department, DateTime? datetime) {
            var dt = datetime ?? DateTime.Today.Date;
            return department.Achievements.Where(a => dt.Year == a.CreateDT.Date.Year && dt.Month == a.CreateDT.Date.Month).Sum(p => p.Reached);
        }

        public static decimal GetMonthSaleAvg(this Lable department, DateTime? datetime) {

            var dt = datetime ?? DateTime.Today.Date;
            return department.GetMonthAchieve(dt) / department.Sales.Count;
        }

        public static decimal GetMonthRates(this Lable department, DateTime? datetime) {
            var dt = datetime ?? DateTime.Today.Date;
            var thisMonthTask = department.GetMonthTask(dt);
            if (thisMonthTask == 0) return 0;
            return department.GetMonthAchieve(dt) / department.GetMonthTask(dt);
        }

        public static decimal GetMonthRatesTop(this Lable department, DateTime? datetime) {
            var dt = datetime ?? DateTime.Today.Date;
            return Lable.GetAllDepartments().Select(x => x.GetMonthRates(dt)).Distinct().OrderByDescending(x => x).ToList().IndexOf(department.GetMonthRates(dt)) + 1;
        }


        public static decimal GetTask(this Sale sale, DateTime? datetime) {
            if (!sale.JoinDate.HasValue) return 0;

            var month = Convert.ToInt32((datetime ?? DateTime.Now).Subtract(sale.JoinDate.Value).TotalDays / 30);

            switch (month) {
                case 1:
                    return 1000;
                case 2:
                    return 2000;
                case 3:
                    return 3000;
                case 4:
                    return 4000;
                case 5:
                    return 4000;
                case 6:
                    return 4000;
                case 7:
                    return 5000;
                case 8:
                    return 5000;
                case 9:
                    return 5000;
                case 10:
                    return 6000;
                case 11:
                    return 6000;
                case 12:
                    return 7000;
                default:
                    return 1000;
            }
        }

        public static decimal GetMonthAchieve(this Sale sale, DateTime? datetime) {
            datetime = datetime ?? DateTime.Now.Date;
            return sale.Achievements.Where(a => a.CreateDT.Year == datetime.Value.Year && a.CreateDT.Month == datetime.Value.Month).Sum(p => p.Reached);
        }


        public static decimal GetAchievement(this Lable department) {
            return department.Sales.Sum(p => p.Achievements.Sum(a => a.Amount));
        }

        public static string GetLeaders(this Lable department) {
            return string.Join(",", department.Sales.Where(s => s.Roles.Any(r => r.Rolename == "部门经理")).Select(s => s.Name).ToArray());
        }
    }


    [ActiveRecord("[Users]")]
    public partial class Sale : ActiveRecordBase<Sale> {

        public UserInfo BbsUser {
            get {
                if (_bbsUser == null) _bbsUser = Discuz.Forum.Users.GetUserInfo(this.UserName);
                return _bbsUser;
            }
        }
        private UserInfo _bbsUser { get; set; }

        [PrimaryKey(PrimaryKeyType.Native, "Username", ColumnType = "String")]
        [DisplayName("帐户")]
        [Required]
        public virtual string UserName {
            get;
            set;
        }

        [DisplayName("入职时间")]
        [Property("join_date", ColumnType = "Timestamp")]
        public virtual System.DateTime? JoinDate {
            get;
            set;
        }



        [Property("nick_name", ColumnType = "String")]
        [DisplayName("实名")]
        public virtual string NickName {
            get;
            set;
        }
        [Property("IsLockedOut", ColumnType = "Boolean")]
        [DisplayName("是否锁定")]
        public virtual bool isLocked {
            get;
            set;
        }
        [Property("Email", ColumnType = "String")]
        public virtual string Email {
            get;
            set;
        }
        [HasAndBelongsToMany(typeof(Lable),
Table = "UserInDepartment", ColumnKey = "user_name", ColumnRef = "department_id", Lazy = true)]
        public virtual IList<Lable> Departments {
            get;
            set;
        }


        [HasAndBelongsToMany(typeof(Role),
Table = "UsersInRoles", ColumnKey = "Username", ColumnRef = "Rolename", Lazy = true)]
        public virtual IList<Role> Roles {
            get;
            set;
        }


        [HasMany(typeof(Achievement), ColumnKey = "user_name", Table = "Achievement", Lazy = true)]
        public virtual IList<Achievement> Achievements {
            get;
            set;
        }
        public string Name { get { return this.NickName ?? this.UserName; } }
        public DateTime? Birthday {
            get {
                DateTime? dt = null;
                if (this.BbsUser != null) {
                    DateTime d;
                    if (DateTime.TryParse(this.BbsUser.Bday, out d))
                        dt = d;
                }
                return dt;
            }
        }

        public string Maxim {
            get {
                if (this.BbsUser != null)
                    return this.BbsUser.Sightml;
                return string.Empty;
            }
        }

        public string Avatar {
            get;
            set;
        }

        public static IList<Sale> GetAllSales() {
            return Sale.FindAll(Expression.Not(Expression.In("UserName", new[] { "swing", "admin", "lto" })));
        }
    }


    [ActiveRecord("Achievement")]
    public partial class Achievement : ActiveRecordBase<Achievement> {
        [PrimaryKey(PrimaryKeyType.Native, "[Id]", ColumnType = "Int32")]
        public virtual int Id {
            get;
            set;
        }

        [BelongsTo("lable_id")]
        public virtual Lable Category {
            get;
            set;
        }

        [BelongsTo("department_id")]
        [DisplayName("部门")]
        public virtual Lable Department {
            get;
            set;
        }

        [BelongsTo("user_name")]
        [DisplayName("帐户")]
        public virtual Sale Sale {
            get;
            set;
        }


        [Property("product_name", ColumnType = "String")]
        [DisplayName("产品名称")]
        public virtual string ProductName {
            get;
            set;
        }

        [Property("years", ColumnType = "Int32")]
        [DisplayName("年限")]
        [DefaultValue(1)]
        public virtual int Years {
            get;
            set;
        }
        [Property("amount", ColumnType = "Decimal", NotNull = true)]
        [DisplayName("合同金额")]
        public virtual decimal Amount {
            get;
            set;
        }
        [Property("reached", ColumnType = "Decimal", NotNull = true)]
        [DisplayName("本期到款")]
        public virtual decimal Reached {
            get;
            set;
        }

        [Property("reached_count", ColumnType = "Decimal")]
        [DisplayName("本期前累计到款")]
        public virtual decimal ReachedCount {
            get;
            set;
        }

        [Property("no_reached", ColumnType = "Decimal")]
        [DisplayName("未到款项")]
        public virtual decimal NoReached {
            get;
            set;
        }

        [Property("price", ColumnType = "Decimal")]
        [DisplayName("单价")]
        public virtual decimal Price {
            get;
            set;
        }
        [Property("createDT", ColumnType = "Timestamp", NotNull = true)]
        [DisplayName("日期")]
        public virtual System.DateTime CreateDT {
            get;
            set;
        }
        [DisplayName("折扣")]
        [Property("discount", ColumnType = "float", NotNull = true)]
        public virtual float Discount {
            get;
            set;
        }
        [DisplayName("折标系数")]
        [Property("sale_discount", ColumnType = "float", NotNull = true)]
        public virtual float SaleDiscount {
            get;
            set;
        }
        [DisplayName("折标业绩")]
        [Property("sale_achievement", ColumnType = "decimal", NotNull = true)]
        public virtual decimal SaleAchievement {
            get;
            set;
        }
    }

    [ActiveRecord("Roles")]
    public partial class Role : ActiveRecordBase<Role> {

        public static IList<Role> GetAll() {
            return Role.FindAll(Expression.Not(Expression.In("Rolename", new[] { "System", "Admin", "Administrator", "Member" })));
        }
        private string _rolename;
        private IList<RolePermission> _rolePermissions;

        [PrimaryKey(PrimaryKeyType.Native, "Rolename", ColumnType = "String")]
        public virtual string Rolename {
            get {
                return this._rolename;
            }
            set {
                this._rolename = value;
            }
        }

        [Property("applicationName", ColumnType = "String", NotNull = true)]
        public virtual string ApplicationName {
            get;
            set;
        }

        [HasAndBelongsToMany(typeof(Sale),
Table = "UsersInRoles", ColumnKey = "Rolename", ColumnRef = "Username", Cascade = ManyRelationCascadeEnum.SaveUpdate, Lazy = true)]
        public virtual IList<Sale> Sales {
            get;
            set;
        }

        [HasMany(typeof(RolePermission), ColumnKey = "role_name", Table = "RolePermission", Cascade = ManyRelationCascadeEnum.SaveUpdate)]
        public virtual IList<RolePermission> Permissions {
            get {
                return this._rolePermissions;
            }
            set {
                this._rolePermissions = value;
            }
        }
    }

    [ActiveRecord("RolePermission")]
    public partial class RolePermission : ActiveRecordBase<RolePermission> {

        [PrimaryKey(PrimaryKeyType.Native, "[id]", ColumnType = "Int32")]
        public virtual int Id {
            get;
            set;
        }

        [Property("role_name", ColumnType = "String")]
        public virtual string RoleName {
            get;
            set;
        }


        [Property("lable_id", ColumnType = "Int32")]
        public virtual int? LableId {
            get;
            set;
        }

        //[BelongsTo("lable_id")]
        //public virtual Lable Lable {
        //    get;
        //    set;
        //}

        //[BelongsTo("role_name")]
        //public virtual Role Role {
        //    get;
        //    set;
        //}

        [Property("permission_name", ColumnType = "String")]
        public virtual string PermissionName {
            get;
            set;
        }

        public string Description {
            get;
            set;
        }
        public RouteValueDictionary RouteValues { get; set; }
        public static Dictionary<string, RolePermission> Actions { get; set; }
    }

    public static class RolePermissionExtentions {
        public static RouteValueDictionary GetRouteValues(this RolePermission rp) {

            return RolePermission.Actions[rp.PermissionName].RouteValues;
        }

        public static string GetText(this RolePermission rp) {

            return RolePermission.Actions[rp.PermissionName].Description;
        }
    }
}

